//
//  Api.swift
//  KPBaseProject
//
//  Created by Kipp Dev on 2018/3/20.
//  Copyright © 2018年 Kipp. All rights reserved.

// swiftlint:disable multiple_closures_with_trailing_closure
// swiftlint:disable identifier_name

import Foundation
import RxAlamofire
import Alamofire
import HandyJSON
import RxSwift
import RxCocoa

//let baseURL: String = "http://192.168.0.119:8080/"
let baseURL: String = "http://wthrcdn.etouch.cn/"

enum ApiType: String {
    case 登录 = "_demo/user/login.app"
    case 修改密码 = "_demo/user/auth/updatePwd.app"
    case 忘记密码 = "_demo/user/updateForgetPwd.app"
    case 注册 = "_demo/user/register.app"
    case 获取服务器当前时间戳 = "_demo/user/getCurSysTimestamp.app"
    case 获取验证码 = "_demo/user/getMsgCode.app"
    case 添加反馈 = "_demo/feedback/auth/saveFeedback.app"
    case 获取开通城市列表 = "_demo/city/findList.app"
    case getSimple = "_demo/demo/getSimpleTest.app"
    case getComplex = "_demo/demo/getTest.app"
    case postSimple = "_demo/demo/postSimpleTest.app"
    case postComplex = "_demo/demo/postTest.app"
    case uploadTest = "_demo/demo/uploadTest.app"
    case weatherTest = "weather_mini?citykey=101010100"

    var hostURL: String { //拼接基础 URL
        return baseURL + self.rawValue
    }
}

class Api {

    // MARK: - Get
    static func getJSONRequest(_ url: ApiType, parameters: [String: Any]?) -> Observable<(HTTPURLResponse, Any)> {
        return RxAlamofire.requestJSON(.get, url.hostURL, parameters: parameters, encoding: URLEncoding.default, headers: ["token": Preferences[.userInfo]!.token])
    }

    // MARK: - Post
    static func postJSONRequest(_ url: ApiType, parameters: [String: Any]?) -> Observable<(HTTPURLResponse, Any)> {
        return RxAlamofire.requestJSON(.post, url.hostURL, parameters: parameters, encoding: URLEncoding.default, headers: ["token": Preferences[.userInfo]!.token])
    }

    // MARK: - 图片上传
    static func uploadRequest(_ url: ApiType, parameters: [String: String]?, images: [(UIImage, String)]) -> Observable<(HTTPURLResponse, Any)> {

        return Observable<(HTTPURLResponse, Any)>.create { observer in
            Alamofire.upload(multipartFormData: { (multipartFormData) in
                if let para = parameters {
                    for (key, value) in para {
                        multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
                    }
                }
                let images = images.compactMap {$0} // 过滤掉空图片
                for item in images {
                    var compression: CGFloat = 0.9
                    let maxCompression: CGFloat = 0.1

                    var data = UIImageJPEGRepresentation(item.0, compression)
                    while (data?.count)! > 150 * 1024 && compression > maxCompression { //大于150kb的图片循环压缩至150k以内
                        compression -= 0.1
                        data = UIImageJPEGRepresentation(item.0, compression)
                    }
                    multipartFormData.append(data!, withName: item.1, fileName: "jpg", mimeType: "image/jpeg")
                }
            }, to: url.hostURL, method: .post, headers: ["token": Preferences[.userInfo]!.token]) { (encodingResult) in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON {
                        if let response = upload.response {
                            observer.onNext((response, $0))
                        }
                    }
                case .failure(let error):
                    observer.onError(error)
                }
            }

            return Disposables.create()
        }

    }

}

extension Reactive where Base: SessionManager {
    func encodeMultipartUpload(to url: URLConvertible, method: HTTPMethod = .post, headers: HTTPHeaders = [:], data: @escaping (MultipartFormData) -> Void) -> Observable<UploadRequest> {
        return Observable.create { observer in
            self.base.upload(multipartFormData: data,
                             to: url,
                             method: method,
                             headers: headers,
                             encodingCompletion: { (result: SessionManager.MultipartFormDataEncodingResult) in
                                 switch result {
                                 case .failure(let error):
                                    observer.onError(error)
                                 case .success(let request, _, _):
                                    observer.onNext(request)
                                    observer.onCompleted()
                                 }
                             })
            return Disposables.create()
        }
    }
}
